package com.woniu.user.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniu.common.ResponseData;
import com.woniu.common.ResponseEnum;
import com.woniu.common.dto.*;
import com.woniu.user.entity.RoleAuth;
import com.woniu.user.entity.RoleMenu;
import com.woniu.user.entity.TMenus;
import com.woniu.user.service.*;
import com.woniu.user.mapper.TMenusMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author hasee
 * @description 针对表【t_menus】的数据库操作Service实现
 * @createDate 2025-01-09 19:29:35
 */
@Service
public class TMenusServiceImpl extends ServiceImpl<TMenusMapper, TMenus>
        implements TMenusService {
    @Autowired
    private UserRoleService userRoleService;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private RoleAuthService roleAuthService;
    @Autowired
    private RoleMenuService roleMenuService;
    @Autowired
    private UserService userService;

    @Override
    public ResponseData<?> queryMenuByRole(Integer id) {
        //第一步，先在缓存内查询当前用户的角色id
        Object userRole = redisTemplate.opsForHash().get("UserRole", "账户ID--" + id.toString());
        if (userRole == null) {
            //直接无权限
            return new ResponseData<>().fail(ResponseEnum.NO_AUTH);
        }
        userRole = JSON.parseObject(userRole.toString(), Integer.class);
        //第二步，根据角色id查有那些菜单id
        //Set<Object> roleMenu = redisTemplate.opsForHash().keys("RoleMenu");
        List<Object> values = redisTemplate.opsForHash().values("RoleMenu");
        ArrayList<RoleMenu> roleMenuList = new ArrayList<>();
        Iterator<Object> iterator = values.iterator();
        while (iterator.hasNext()) {
            Object next = iterator.next();
            RoleMenu roleMenu = JSON.parseObject(next.toString(), RoleMenu.class);
            roleMenuList.add(roleMenu);
        }
        //角色菜单表
        Iterator<RoleMenu> roleMenuIterator = roleMenuList.iterator();
        ArrayList<TMenus> menusArrayList = new ArrayList<>();
        while (roleMenuIterator.hasNext()) {
            RoleMenu roleMenu = roleMenuIterator.next();
            Integer roleId = roleMenu.getRoleId();
            if (roleId.equals(userRole)) {
                //第三步，根据菜单id查菜单
                Integer menuid = roleMenu.getMenuid();
                Object menus = redisTemplate.opsForHash().get("Menus", "菜单ID--" + menuid.toString());
                TMenus tMenus = JSON.parseObject(menus.toString(), TMenus.class);
                menusArrayList.add(tMenus);
            }
        }
        //获得角色菜单后，过滤出主菜单和子菜单
        //将集合中的元素全部换成dto
        ArrayList<TMenusDTO> dtoList = new ArrayList<>();
        Iterator<TMenus> dtoIterator = menusArrayList.iterator();
        while (dtoIterator.hasNext()) {
            TMenusDTO tMenusDTO = new TMenusDTO();
            BeanUtil.copyProperties(dtoIterator.next(), tMenusDTO);
            dtoList.add(tMenusDTO);
        }
        List<TMenusDTO> mainCollect = dtoList
                .stream().filter(e -> e.getParentid().equals(-1)).collect(Collectors.toList());

        for (TMenusDTO tMenus : mainCollect) {
            List<TMenusDTO> childrenCollect = dtoList
                    .stream().filter(e -> e.getParentid().equals(tMenus.getId())).collect(Collectors.toList());
            tMenus.setChildrenMenu(childrenCollect);
        }
        return new ResponseData<>().ok(mainCollect);
    }

    @Override
    public ResponseData<?> queryAllMenuAndAuth(UserRoleDTO userRoleDTO) {
        ArrayList<String> nodeList = new ArrayList<>();
        ArrayList<MenuAuthDTO> menuAuthDTOS = new ArrayList<>();
        List<Object> roleMenu = redisTemplate.opsForHash().values("RoleMenu");
        List<Object> roleAuth = redisTemplate.opsForHash().values("RoleAuth");
        //先获取所有的角色id
        Integer roleId = userRoleDTO.getRoleId();
        List<TMenusDTO> tMenusDTOSList = queryMenuByRole2(1);
        //将获取到的菜单和权限，封装到dto中
        //先遍历这个集合，获取所有一级菜单
        //先创建一个for循环的计数器
        int firstCount = 0;
        for (TMenusDTO tMenusDTO : tMenusDTOSList) {
            MenuAuthDTO menuAuthDTO = new MenuAuthDTO();
            menuAuthDTO.setId(tMenusDTO.getId());
            menuAuthDTO.setLabelName(tMenusDTO.getName());
            firstCount++;
            menuAuthDTO.setNodeKey("node" + firstCount);
            //判断是否拥有该菜单权限

            Iterator<Object> iterator = roleMenu.iterator();
            while (iterator.hasNext()) {
                Object next = iterator.next();
                RoleMenu roleMenu1 = JSON.parseObject(next.toString(), RoleMenu.class);
                Integer menuid = roleMenu1.getMenuid();
                if (roleId.equals(roleMenu1.getRoleId())) {
                    if (tMenusDTO.getId().equals(menuid)) {
                        //说明拥有该菜单权限
                        nodeList.add(menuAuthDTO.getNodeKey());
                        break;
                    }
                }

            }
//            Object o = redisTemplate.opsForHash().get("RoleMenu", "角色菜单表ID--" + roleId.toString());
//            if (o!=null){
//                nodeList.add(menuAuthDTO.getNodeKey());
//            }
            menuAuthDTOS.add(menuAuthDTO);
            //一级菜单除了子菜单全部转换完毕
            //获取子菜单
            //创建第二个for循环计数器
            ArrayList<MenuAuthDTO> menuAuthDTOSList2 = new ArrayList<>();
            List<TMenusDTO> childrenMenu = tMenusDTO.getChildrenMenu();
            int secondCount = 0;
            for (TMenusDTO menu : childrenMenu) {
                MenuAuthDTO menuAuthDTO1 = new MenuAuthDTO();
                menuAuthDTO1.setId(menu.getId());
                menuAuthDTO1.setLabelName(menu.getName());
                menuAuthDTO1.setNodeKey("node" + firstCount + "." + ++secondCount);

                while (iterator.hasNext()) {
                    Object next = iterator.next();
                    RoleMenu roleMenu1 = JSON.parseObject(next.toString(), RoleMenu.class);
                    Integer menuid = roleMenu1.getMenuid();
                    if (roleId.equals(roleMenu1.getRoleId())) {
                        if (menu.getId().equals(menuid)) {
                            //说明拥有该菜单权限
                            nodeList.add(menuAuthDTO1.getNodeKey());
                            break;
                        }
                    }

                }
//                Object o2 = redisTemplate.opsForHash().get("RoleMenu", "角色菜单表ID--" + roleId.toString());
//                if (o2!=null){
//                    nodeList.add(menuAuthDTO1.getNodeKey());
//                }
                menuAuthDTOSList2.add(menuAuthDTO1);
                //二级菜单获取完毕
                //获取该页面的权限
                //创建第三个for循环计数器
                ArrayList<MenuAuthDTO> authList = new ArrayList<>();
                int thirdCount = 0;
                List<Object> auth = redisTemplate.opsForHash().values("Auth");
                Iterator<Object> iterator1 = auth.iterator();
                while (iterator1.hasNext()) {
                    Object next = iterator1.next();
                    AuthDTO authDTO = JSON.parseObject(next.toString(), AuthDTO.class);
//                        if (authDTO.getMenuid().equals(1)){
                    if (authDTO.getMenuid() == null) {
                        continue;
                    }
                    if (authDTO.getMenuid().equals(menu.getId())) {
                        MenuAuthDTO menuAuthDTO2 = new MenuAuthDTO();
                        menuAuthDTO2.setId(authDTO.getId());
                        menuAuthDTO2.setLabelName(authDTO.getAuthname());
                        menuAuthDTO2.setNodeKey("node" + firstCount + "." + secondCount + "." + ++thirdCount);
                        Iterator<Object> iterator2 = roleAuth.iterator();
                        while (iterator2.hasNext()) {
                            Object next1 = iterator2.next();
                            RoleAuth roleAuth1 = JSON.parseObject(next1.toString(), RoleAuth.class);
                            if (roleId.equals(roleAuth1.getRoleId())) {
                                if (authDTO.getId().equals(roleAuth1.getAuthid())) {
                                    //说明拥有该权限
                                    nodeList.add(menuAuthDTO2.getNodeKey());
                                    break;
                                }
                            }
                        }
//                        Object o3 = redisTemplate.opsForHash().get("RoleAuth", "角色权限表ID--" + roleId.toString());
//                        if (o3!=null){
//                            nodeList.add(menuAuthDTO2.getNodeKey());
//                        }
                        authList.add(menuAuthDTO2);
                    }
//                        }
                }
                menuAuthDTO1.setList(authList);
            }
            menuAuthDTO.setList(menuAuthDTOSList2);

        }
//        }
        ArrayList<Object> objects = new ArrayList<>();
        objects.add(nodeList);
        objects.add(menuAuthDTOS);
        return new ResponseData<>().ok(objects);
    }

    @Override
    public ResponseData<?> updateMenuAndAuth(TreeBackDTO treeBackDTO) {
        MenuAuthDTO menuAuthDTO = treeBackDTO.getMenuAuthDTO();
        boolean childrenNodeSelected = treeBackDTO.isChildrenNodeSelected();
        boolean currentSelected = treeBackDTO.isCurrentSelected();
        //获取角色的id
        Integer roleId = treeBackDTO.getRoleId();
        //此处id为菜单或权限的id
        Integer id = treeBackDTO.getMenuAuthDTO().getId();
        List<Object> roleMenuList = redisTemplate.opsForHash().values("RoleMenu");
        List<Object> roleAuthList = redisTemplate.opsForHash().values("RoleAuth");
        Iterator<Object> roleMenuIterator = roleMenuList.iterator();
        Iterator<Object> roleAuthIterator = roleAuthList.iterator();
        //先判断是页面还是权限
        //先进行类型转换
        if (roleMenuIterator.hasNext()){
            while (roleMenuIterator.hasNext()) {
                Object next = roleMenuIterator.next();
                RoleMenu roleMenu = JSON.parseObject(next.toString(), RoleMenu.class);
                if (roleId.equals(roleMenu.getRoleId())) {
                    if (id.equals(roleMenu.getMenuid())) {
                        //说明拥有该菜单权限
                        roleMenuService.removeById(roleMenu);
                        userService.init();
                       return new ResponseData<>().ok();
                    }
                }
            }
            while (roleAuthIterator.hasNext()) {
                Object next = roleAuthIterator.next();
                RoleAuth roleAuth = JSON.parseObject(next.toString(), RoleAuth.class);
                if (roleId.equals(roleAuth.getRoleId())) {
                    if (id.equals(roleAuth.getAuthid())) {
                        //说明拥有该权限
                        roleAuthService.removeById(roleAuth);
                        userService.init();
                        return new ResponseData<>().ok();
                    }
                }
            }

            if (currentSelected) {
                if (!treeBackDTO.getMenuAuthDTO().getLabelName().contains("权限")){
                    //说明当前选中
                    RoleMenu roleMenu = new RoleMenu();
                    roleMenu.setRoleId(roleId);
                    roleMenu.setMenuid(id);
                    roleMenuService.save(roleMenu);
                    userService.init();
                    return new ResponseData<>().ok();
                }else {
                    RoleAuth roleAuth = new RoleAuth();
                    roleAuth.setRoleId(roleId);
                    roleAuth.setAuthid(id);
                    roleAuthService.save(roleAuth);
                    userService.init();
                    return new ResponseData<>().ok();
                }

            }

        }

        return new ResponseData<>().fail(ResponseEnum.Fail);
    }


    private List<TMenusDTO> queryMenuByRole2(Integer id) {
        //第一步，先在缓存内查询当前用户的角色id
        Object userRole = redisTemplate.opsForHash().get("UserRole", "账户ID--" + id.toString());
        userRole = JSON.parseObject(userRole.toString(), Integer.class);
        //第二步，根据角色id查有那些菜单id
        //Set<Object> roleMenu = redisTemplate.opsForHash().keys("RoleMenu");
        List<Object> values = redisTemplate.opsForHash().values("RoleMenu");
        ArrayList<RoleMenu> roleMenuList = new ArrayList<>();
        Iterator<Object> iterator = values.iterator();
        while (iterator.hasNext()) {
            Object next = iterator.next();
            RoleMenu roleMenu = JSON.parseObject(next.toString(), RoleMenu.class);
            roleMenuList.add(roleMenu);
        }
        //角色菜单表
        Iterator<RoleMenu> roleMenuIterator = roleMenuList.iterator();
        ArrayList<TMenus> menusArrayList = new ArrayList<>();
        while (roleMenuIterator.hasNext()) {
            RoleMenu roleMenu = roleMenuIterator.next();
            Integer roleId = roleMenu.getRoleId();
            if (roleId.equals(userRole)) {
                //第三步，根据菜单id查菜单
                Integer menuid = roleMenu.getMenuid();
                Object menus = redisTemplate.opsForHash().get("Menus", "菜单ID--" + menuid.toString());
                TMenus tMenus = JSON.parseObject(menus.toString(), TMenus.class);
                menusArrayList.add(tMenus);
            }
        }
        //获得角色菜单后，过滤出主菜单和子菜单
        //将集合中的元素全部换成dto
        ArrayList<TMenusDTO> dtoList = new ArrayList<>();
        Iterator<TMenus> dtoIterator = menusArrayList.iterator();
        while (dtoIterator.hasNext()) {
            TMenusDTO tMenusDTO = new TMenusDTO();
            BeanUtil.copyProperties(dtoIterator.next(), tMenusDTO);
            dtoList.add(tMenusDTO);
        }
        List<TMenusDTO> mainCollect = dtoList
                .stream().filter(e -> e.getParentid().equals(-1)).collect(Collectors.toList());

        for (TMenusDTO tMenus : mainCollect) {
            List<TMenusDTO> childrenCollect = dtoList
                    .stream().filter(e -> e.getParentid().equals(tMenus.getId())).collect(Collectors.toList());
            tMenus.setChildrenMenu(childrenCollect);
        }
        return mainCollect;
    }

}



